;A game using the sprites.

var ce
const bullets=3,enemy=8,backdots=9,deftib=2,key_repeat=1
back_dots ? backdots*3
edata	  ? enemy*4
bdata	  ? bullets*3
dots	  ? 1200

high_score=0
screen 6
mode 640,and
video=0b800h ;For CGA emu.
#include keys.fi
set_keys

start:
randomize timer
colour 0:cls
colour 7
cursor 12,36:print bios "S P A C E";
c=0:m=dots
for y=96 to 103
for x=288 to 359
if point x,y then
  {
  #short
  poke m,x:pokeb m+2,y
  poke m+5,rnd mod 1700:poke m+7,rnd mod 800
  s=rnd
  if s and 4 then poke m+5,0-peek (m+5)
  if s and 2 then poke m+7,0-peek (m+7)
  m+=9:c++
  if m>=(dots+1200)
   then goto exit_store
  #long
  }
next x
next y
exit_store:
colour 0:cls

#short
for rep=1 to 28
  m=dots
  for a=1 to c
  x=peek m
  y=peekb (m+2)
  lx=peekb (m+3):ly=peekb (m+4)
  lx+=peek (m+5):ly+=peek (m+7)
  pokeb m+3,lx:pokeb m+4,ly
  if lx>255 then x+=high lx
  if ly>255 then y+=high ly
  if lx<0 then x-=256-high lx
  if ly<0 then y-=256-high ly
  poke m,x:pokeb m+2,y
  if rep=28 then plot x,y
  m+=9
  next a
next rep

repeat 28
  {
  m=dots
  for a=1 to c
  x=peek m:y=peekb (m+2)
  colour 0:plot x,y
  lx=peekb (m+3):ly=peekb (m+4)
  lx-=peek (m+5):ly-=peek (m+7)
  pokeb m+3,lx:pokeb m+4,ly
  if lx>255 then x+=high lx
  if ly>255 then y+=high ly
  if lx<0 then x-=256-high lx
  if ly<0 then y-=256-high ly
  colour 1:plot x,y
  poke m,x:pokeb m+2,y
  m+=9
  next a
  }
for b=1 to 500 step 5:for c=20 to 200 step 40:noise 50,c+b:next c:next b
noise 1,2500
noise off

add=back_dots
repeat backdots
  {
  poke add,rnd mod 640
  pokeb add+2,(rnd mod 175)+25
  add+=3
  }

repbase=3
score=0:lives=5

life:
colour 0:cls
gosub print_lives
x=110:y=90
fillb bullets*3 from bdata with 0
fillb enemy*4 from edata with 0
tib=0:dtime=0
timer=0:frame=0


loops:
cursor 0,10:print bios "Score ";score;"   High score ";high_score;

loop:

start_score=score
add=back_dots
repeat backdots
  {
  dx=peek add:dy=peekb (add+2)
  colour 0:plot dx,dy
  dx-=4:if dx<0 then dx=639
  colour 1:plot dx,dy
  poke add,dx
  add+=3
  }

if dtime=1 then goto dead
#long
if dtime>1 then dtime--
 else
  {
  #short
  sprite x-18,y,thrust+frame*(2*14+2)
  sprite x-18,y+10,thrust+frame*(2*14+2)
  sprite x,y,spyou
  if key_press(44) then y+=3
  if key_press(30) then y-=3
  if y<30 then y=30
  if y>175 then y=175
  #long
  }
#short
if key_press(1) then goto exit_game

add=bdata:fire++
if tib>0 then tib--
repeat bullets
   {
   bx=peek add:by=peekb (add+2)
   f=key_press(28)
   if (dtime=0) and (by=0) and f and ((fire and 3)=0) and (tib=0) then
     {
     for a=600 to 1000 step 12:noise 2,a:next a:noise off
     bx=x+16:by=y+10
     tib=deftib
     }
   #long
   if by then
     {
     #short
     if	bx>580 then sprite bx,by,null_bull:by=0:goto end_b
     bx+=19
     sprite bx,by,bullet

     add2=edata
     repeat enemy
       {
       if not peekb (add2+3) then
       {
       if hit bx,by,bullet with peek add2,peekb (add2+2),enemysp 1
	 then
	 {
	 score+=10
	 sprite bx,by,null_bull
	 pokeb add2+3,5
	 by=0
	 }
       add2+=4
       }
       }
     #long
     }
   end_b:
   poke add,bx:pokeb add+2,by
   add+=3
   }

#short
add=edata
rep=repbase
repeat enemy
  {
  ex=peek add:ey=peekb (add+2)
  time=peekb (add+3)
  if (ey=0) then ex=610:ey=(rnd mod 170)+10:time=0
  #long
  if time then
    {
    time--
    for a=1 to 40:noise 1,1000+rnd and 2047:next a:noise off
    if time then sprite ex,ey+3,explosion+(6-time)/2*(2*5+2)
	    else sprite ex,ey+3,en_null:ey=0
    goto end_e
    }
  if ex<x+45 then
    {
    #short
    hf=0
    pokeb enemysp,1
    if dtime=0 then hf=hit x,y,spyou with ex,ey,enemysp 3
    if hf then gosub death:dtime=35
    if ex<10 then
      {
      sprite ex,ey+3,en_null
      ey=0
      goto end_e
      }
    #long
    }
  #short
  rr=rnd
  if ex>(250+repbase*15) then
    {
    if rr and 1 then ey+=rr mod 3 else ey-=rr mod 3
    }
   else
    {
    if ey>y
      then ey-=rr and 3
      else ey+=rr and 3
    }
  if ey<25 then ey=25
  if ey>185 then ey=185
  ex-=rep
  pokeb enemysp,2
  sprite ex,ey,enemysp
  end_e:
  poke add,ex:pokeb add+2,ey:pokeb add+3,time
  add+=4
  rep++:if rep>10 then rep=10
  }

#long
if dtime then
  {
  #short
  add=dots
  repeat ce
    {
    ex=peek add:ey=peekb (add+2)
    xi=peekb (add+3)
    yi=peek (add+4)
    noise 1,rnd and 8191
    colour 0:plot ex,ey
    colour 1
    ex+=xi
    if yi and 128
      then ey-=(yi mod 3):ey-=rnd and 1
      else ey+=yi mod 3:ey+=rnd and 1
    plot ex,ey
    poke add,ex:pokeb add+2,ey
    add+=6
    }
  noise off
  #long
  }
#short

if timer>360 then
  {
  repbase++
  if repbase>16 then repbase=16
  timer=0
  }
dd2:
frame++:if frame>2 then frame=0

if start_score=score then goto loop
if score>high_score then high_score=score
goto loops


death:	;Use ADD2 because ADD is used within caller (ENEMY).
add2=dots:ce=0
for a=y+3 to y+18 step 2
for b=x to x+31 step 4
poke add2,b:pokeb add2+2,a
pokeb add2+3,(rnd and 7)+1:poke add2+4,rnd
add2+=6:ce++
if add2>=(dots+1200) then return
next b
next a
return

dead:
lives--
if lives then goto life
for y=0 to 23
cursor y+1,y*2:print bios "GAME OVER";
cursor y,2*y-2:print bios "         ";
noise 600,y*50+2000
next y
noise off
repeat 4 repeat 60000 {}
goto start

print_lives:
xx=lives-1
while xx>0
  {
  sprite xx*50+350,0,spyou
  xx--
  }
return


exit_game:
reset_keys
screen 3:terminate

spyou:
datab 2,22
data 0,0,0,0,0,0
shape "    ******                      "
shape "****************                "
shape "******                          "
shape "*******                         "
shape "******************              "
shape "** * * ** ***** ***********     "
shape "******** ***** ********  ****** "
shape "*** * * ***** ******************"
shape "*** * * ***** ******************"
shape "******** ***** ********  ****** "
shape "** * * ** ***** ***********     "
shape "******************              "
shape "*******                         "
shape "******                          "
shape "****************                "
shape "    ******                      "
data 0,0,0,0,0,0

thrust:
datab 1,14
data 0,0,0
shape "           **   "
shape "          ** *  "
shape "         *  * * "
shape "       *  *  * *"
shape "      ** *  *  *"
shape "         * ** * "
shape "          *  *  "
shape "           **   "
data 0,0,0

datab 1,14
data 0,0,0
shape "                "
shape "        * **    "
shape "      ** *   *  "
shape "  * * *   * * * "
shape "   * *  * *  * *"
shape "      ** *  *   "
shape "        ** *    "
shape "                "
data 0,0,0

datab 1,14
data 0,0,0
shape "                "
shape "                "
shape "           **   "
shape "   *  * * *  * *"
shape "* * * *  * * * *"
shape "        *  *    "
shape "                "
shape "                "
data 0,0,0

null_bull:
datab 2,2
data 0,0,0,0

bullet:
datab 2,2
datab 0,0
shape "   ********"
datab 0,0
shape "   ********"

enemysp:
datab 2,11
data 0,0,0,0,0,0
shape "  **************          "
shape " ****     ***             "
shape "************              "
shape " *****    ***             "
shape "  **************          "
data 0,0,0,0,0,0

en_null:
datab 1,5
data 0,0,0,0,0

explosion:
datab 1,5
shape "  *   *   *  *  "
shape "  *     *     * "
shape " *             *"
shape "   * *    *    *"
shape "      * * *  *  "

datab 1,5
shape "        *  *    "
shape "    * *   *     "
shape "    *      *    "
shape "     *   *      "
shape "       *        "

datab 1,5
shape "                "
shape "      *         "
shape "     ****       "
shape "       *        "
shape "                "
